package com.open.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.open.annotation.Limit;
import com.open.annotation.RepeatSubmit;
import com.open.annotation.Vef;
import com.open.bean.*;
import com.open.bean.vo.ChattingVo;
import com.open.component.JwtComponent;
import com.open.mapper.IpWhiteMapper;
import com.open.result.OpenResult;
import com.open.server.EmailServer;
import com.open.service.*;
import com.open.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.LogRecord;
import java.util.stream.Collectors;

/**
 * @author tanyongpeng
 * <p>des</p>
 **/
@RestController
@RequestMapping("/request/open")
@Slf4j
public class RequestOpenController {

    @Autowired
    IpWhiteService ipWhiteService;

    @Autowired
    IpWhiteMapper ipWhiteMapper;


    @Autowired
    RequestRecordService requestRecordService;

    @Autowired
    OpenDictService openDictService;

    @Autowired
    JwtComponent jwtComponent;

    @Autowired
    RequestTokenService requestTokenService;

    @Autowired
    LoginRecordService loginRecordService;

    @Autowired
    EmailServer emailServer;

    @Autowired
    PaintingRecordService paintingRecordService;

    @Autowired
    DistributionRecordService distributionRecordService;


    @GetMapping("/chatting/records")
    public OpenResult chattingRecords(HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        Map<String,Object> map = new HashMap<>();
        List<RequestRecord> requestRecordList = requestRecordService.lambdaQuery().eq(RequestRecord::getWid, wId)
                .eq(RequestRecord::getIsDelete, 0).list();
        List<String> requestList = requestRecordList.stream().map(RequestRecord::getRequestContent).collect(Collectors.toList());
        Map<Long, List<RequestRecord>> longListMap = requestRecordList.stream().collect(Collectors.groupingBy(RequestRecord::getGroupCode));
        List<ChattingVo> chattingVoList = new ArrayList<>();
        List<String> dateList = new ArrayList<>();
        longListMap.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByKey())).forEachOrdered(x ->{
                    String date = new SimpleDateFormat("yy年M月d日").format(x.getValue().get(0).getRequestTime());
                    String toDay = new SimpleDateFormat("yy年M月d日").format(new Date());
                    chattingVoList.add(new ChattingVo(x.getKey(), x.getValue(),!dateList.contains(date)?
                            (date.equals(toDay)?"今日":date):""));
                    dateList.add(date);
                }
        );
        map.put("chattingList",chattingVoList);
        map.put("requestList",requestList);
        return OpenResult.success(map);
    }


    @PostMapping("/reg/ip")
    @Vef
    @Limit
    @RepeatSubmit
    public OpenResult regIp(@RequestBody JSONObject jsonObject, HttpServletRequest request){
        if (StrUtil.isBlank(jsonObject.getStr("code")) || StrUtil.isBlank(jsonObject.getStr("email")) || StrUtil.isBlank(jsonObject.getStr("userPassword"))){
            return OpenResult.error("请求的参数错误");
        }
        log.info("当前登录验证邮箱验证：{}",jsonObject.getStr("email"));
        if (jsonObject.getStr("userPassword").trim().length() < 6){
            return OpenResult.error("密码长度不小于6位");
        }
        if (ipWhiteService.lambdaQuery().eq(IpWhite::getEmail,jsonObject.getStr("email")).count() != 0) {
            return OpenResult.error("当前账号已被注册");
        }
        String currentEmailCode = RedisUtil.get(jsonObject.getStr("email").trim()+"_reg");
        log.info("当前验证码：{}",currentEmailCode);
        if (currentEmailCode == null){
            return OpenResult.error("请重新发送验证码");
        }
        if (!jsonObject.getStr("code").equals(currentEmailCode)){
            return OpenResult.error("验证码错误");
        }
        String head = UserHead.getUserHeadImg();
        Integer wid = saveUser(request,jsonObject.getStr("email"),jsonObject.getStr("userPassword")
        ,Integer.parseInt(openDictService.getDict("100002")),0,Integer.parseInt(openDictService.getDict("100002")),0,head);
        return loginSuccess(request,String.valueOf(wid),1,jsonObject.getStr("email"),head);
    }

    public Integer saveUser(HttpServletRequest request,String username,String password,Integer requestCount,Integer
                            resettingCount,Integer limitationCount,Integer distributionType,String headImg){
        IpWhite ipWhite = new IpWhite();
        ipWhite.setIp( IPUtil.getIpAddress(request));
        ipWhite.setCreateTime(new Date());
        ipWhite.setRequestCount(requestCount);
        ipWhite.setUpdateTime(new Date());
        ipWhite.setIpStatus(0);
        ipWhite.setNikeName(UsernameUtil.getUsername(IPUtil.getIpAddress(request)));
        ipWhite.setEmail(username);
        ipWhite.setUserType(0);
        ipWhite.setUserPassword(password);
        ipWhite.setRequestImgCount(30);
        ipWhite.setResettingCount(resettingCount);
        ipWhite.setLimitationCount(limitationCount);
        ipWhite.setDistributionType(distributionType);
        ipWhite.setDialogueCount(3);
        ipWhite.setTemperature(new BigDecimal("0.5"));
        ipWhite.setHeadImg(headImg);
        ipWhiteMapper.insert(ipWhite);
        return ipWhite.getWid();
    }

    @PostMapping("/login/ai")
    @Vef
    @Limit
    public OpenResult login(@RequestBody JSONObject jsonObject,HttpServletRequest request){
        if (StrUtil.isBlank(jsonObject.getStr("email")) || StrUtil.isBlank(jsonObject.getStr("userPassword"))){
            return OpenResult.error("请求的参数错误");
        }
        IpWhite ipWhite = ipWhiteService.lambdaQuery()
                .eq(IpWhite::getEmail, jsonObject.getStr("email"))
                .eq(IpWhite::getUserPassword, jsonObject.getStr("userPassword")).one();
        if (ipWhite == null){
            if (ipWhiteService.lambdaQuery().eq(IpWhite::getEmail,jsonObject.getStr("email")).count() == 0) {
                return OpenResult.error("当前账号未注册！");
            }else {
                return OpenResult.error("账号或密码错误！");
            }
        }
        if (ipWhite.getIpStatus() == 1){
            return OpenResult.error("当前账号被封禁");
        }else if(ipWhite.getIpStatus() == 3){
            return OpenResult.error("当前账号正在审核，请稍等...");
        }else {
            return loginSuccess(request,String.valueOf(ipWhite.getWid()),0,ipWhite.getEmail(),
                    StrUtil.isBlank(ipWhite.getHeadImg())?UserHead.getUserHeadImg():ipWhite.getHeadImg());
        }
    }

    public OpenResult loginSuccess(HttpServletRequest request,String wid,Integer type,String username,String headImg){
        Map<String,String> map = new HashMap<>();
        map.put("ip",IPUtil.getIpAddress(request));
        map.put("wid",wid);
        map.put("t",String.valueOf(new Date().getTime()));
        if (type == 0){
            LoginRecord logRecord = new LoginRecord();
            logRecord.setWid(Integer.parseInt(wid));
            logRecord.setUsername(username);
            logRecord.setHeadImg(headImg);
            logRecord.setLoginTime(new Date());
            logRecord.setIp(IPUtil.getIpAddress(request));
            loginRecordService.save(logRecord);
        }
        return OpenResult.success(OpenResult.SUCCESS_CODE,"成功",
                jwtComponent.generateToken(map));
    }

    @GetMapping("/get/user/info")
    public OpenResult getUserInfo(HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        IpWhite ipWhite = ipWhiteService.lambdaQuery().eq(IpWhite::getWid, wId).one();
        Map<String,Object> objectMap = new HashMap<>();
        objectMap.put("nickname",ipWhite.getNikeName());
        objectMap.put("isImgShow",ipWhite.getIsImgShow());
        if (StrUtil.isBlank(ipWhite.getHeadImg())){
            String head = UserHead.getUserHeadImg();
            ipWhite.setHeadImg(head);
            ipWhiteService.lambdaUpdate()
                    .set(IpWhite::getHeadImg,head)
                    .eq(IpWhite::getWid,wId).update();
        }
        objectMap.put("headImg",ipWhite.getHeadImg());
        objectMap.put("username",ipWhite.getEmail());
        objectMap.put("dialogueCount",ipWhite.getDialogueCount());
        objectMap.put("temperature",ipWhite.getTemperature().floatValue());
        return OpenResult.success(objectMap);
    }

    @PostMapping("/update/ai/img/show")
    public OpenResult updateAiImgShow(@RequestBody JSONObject jsonObject,HttpServletRequest request){
        Integer state = jsonObject.getBool("state")?1:0;
        String wId = jwtComponent.getUserWId(request);
        boolean update = ipWhiteService.lambdaUpdate()
                .set(IpWhite::getIsImgShow, state)
                .eq(IpWhite::getWid, wId).update();
        return OpenResult.update(update);
    }

    @PostMapping("/delete/group")
    public OpenResult deleteGroup(@RequestBody JSONObject jsonObject,HttpServletRequest request){
        if (jsonObject.getLong("code") == null){
            return OpenResult.error("删除失败，请联系管理员处理");
        }
        String wId = jwtComponent.getUserWId(request);
        requestRecordService.lambdaUpdate()
                .set(RequestRecord::getIsDelete,1)
                .eq(RequestRecord::getGroupCode,jsonObject.getLong("code"))
                .eq(RequestRecord::getWid,wId)
                .update();
        return OpenResult.success();
    }

    @PostMapping("/delete/all")
    public OpenResult deleteAll(HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        requestRecordService.lambdaUpdate()
                .set(RequestRecord::getIsDelete,1)
                .eq(RequestRecord::getWid,wId)
                .update();
        return OpenResult.success();
    }

    @GetMapping("/generate/email/code/{email}/{type}")
    @Vef
    @Limit
    public OpenResult emailCode(@PathVariable String email,@PathVariable String type,HttpServletRequest request){
        if (StrUtil.isBlank(email) || StrUtil.isBlank(type)){
            return OpenResult.error("参数有误");
        }
        if (type.equals("reg")){
            if (ipWhiteService.lambdaQuery().eq(IpWhite::getEmail,email).count() != 0) {
                return OpenResult.error("当前邮箱已被注册");
            }
        }else {
            if (ipWhiteService.lambdaQuery().eq(IpWhite::getEmail, email).count() == 0){
                return OpenResult.error("当前邮箱未注册");
            }
        }
        if (Integer.parseInt(openDictService.getDict("100009")) != 0) {
            return OpenResult.error("当前停止注册，具体开放时间，请加群后等通知");
        }
        int emailEffective = Integer.parseInt(openDictService.getDict("100008"));
        String currentEmailCode = RedisUtil.get(email+"_"+type);
        log.info("当前redis组成：{}",email+"_"+type);
        log.info("code值：{}",currentEmailCode);
        if (currentEmailCode == null){
            String captcha = CaptchaGeneratorUtil.generateCaptcha(20);
            String ip = StrUtil.isBlank(IPUtil.getIpAddress(request))?"127.0.0.1":IPUtil.getIpAddress(request);
            emailServer.sendEmail(email,captcha,ip);
            RedisUtil.set(email+"_"+type,captcha,60 * emailEffective);
            return OpenResult.success();
        }else {
            return OpenResult.error("请"+emailEffective+"分钟后重新发送");
        }
    }

    @PostMapping("/update/password")
    @Vef
    @Limit
    public OpenResult updatePassword(@RequestBody JSONObject jsonObject){
        if (StrUtil.isBlank(jsonObject.getStr("code")) || StrUtil.isBlank(jsonObject.getStr("email")) ||
            StrUtil.isBlank(jsonObject.getStr("userPassword")) || StrUtil.isBlank(jsonObject.getStr("newUserPassword"))){
            return OpenResult.error("请求的参数错误");
        }
        String updateCode = RedisUtil.get(jsonObject.getStr("email") + "_update");
        if (updateCode == null){
            return OpenResult.error("请重新发送验证码");
        }
        if (!updateCode.equals(jsonObject.getStr("code"))){
            return OpenResult.error("验证码错误");
        }

        if (ipWhiteService.lambdaQuery().eq(IpWhite::getEmail, jsonObject.getStr("email")).count() == 0){
            return OpenResult.error("当前邮箱未注册");
        }

        boolean update = ipWhiteService.lambdaUpdate()
                .set(IpWhite::getUserPassword, jsonObject.getStr("newUserPassword"))
                .eq(IpWhite::getEmail, jsonObject.getStr("email")).update();
        return OpenResult.update(update);
    }

    @GetMapping("/deduction/record/")
    public OpenResult deductionRecord(@RequestParam Integer current,
                                      @RequestParam Integer size,
                                      @RequestParam boolean bol,
                                      HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        String wid = jwtComponent.getUserWId(request);
        IpWhite ipWhite = ipWhiteService.lambdaQuery().eq(IpWhite::getWid, wid).eq(IpWhite::getIpStatus, 0).one();
        if (ipWhite == null){
            return OpenResult.error("账户异常！");
        }
        if (StrUtil.isBlank(ipWhite.getAppKey())){
            String appKey = GenerateAppKeyUtil.getAppKey(String.valueOf(ipWhite.getWid()),ipWhite.getNikeName());
            ipWhite.setAppKey(appKey);
            ipWhiteService.lambdaUpdate()
                    .set(IpWhite::getAppKey,appKey)
                    .eq(IpWhite::getWid,ipWhite.getWid()).update();
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("appKey",ipWhite.getAppKey());
        jsonObject.set("bindIP",IPUtil.getIpAddress(request));
        jsonObject.set("email",ipWhite.getEmail());
        jsonObject.set("name",ipWhite.getNikeName());
        jsonObject.set("username",ipWhite.getEmail());
        jsonObject.set("regDate",ipWhite.getCreateTime());
        jsonObject.set("remark","详情请加Q群：237343691,联系群主");
        jsonObject.set("resettingCount",ipWhite.getResettingCount()==null?0:ipWhite.getResettingCount());
        jsonObject.set("balance",ipWhite.getRequestCount());
        if (ipWhite.getUserType() == 0 || ipWhite.getUserType() == 1){
            jsonObject.set("resettingBalance",0);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 2){
            jsonObject.set("resettingBalance",35);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 3){
            jsonObject.set("resettingBalance",65);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 4){
            jsonObject.set("resettingBalance",95);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }

        Integer userCount = requestRecordService.lambdaQuery()
                .eq(RequestRecord::getWid, wid)
                .last("AND TO_DAYS(request_time) = TO_DAYS(NOW())").count();

        // 今日 使用额度
        jsonObject.set("useCount",userCount);

        Integer allUseCount = requestRecordService.lambdaQuery().eq(RequestRecord::getWid, wid).count();

        jsonObject.set("allUseCount",allUseCount);

        // 一共使用

        jsonObject.set("type",ipWhite.getUserType());
        jsonObject.set("imgBalance",ipWhite.getRequestImgCount());

        if (!bol){
            Page<RequestRecord> page = requestRecordService.page(new Page(current, size), new QueryWrapper<RequestRecord>()
                    .eq("wid", wid).orderByDesc("request_id"));
            List<RequestRecord> records = page.getRecords();
            for (RequestRecord record : records) {
                record.setNikeName("");
                record.setRequestIp("");
                record.setRequestSign("");
                record.setRequestStatus(null);
                record.setRespondContent("");
                record.setRespondTime(null);
                record.setIsDelete(null);
            }
            page.setRecords(records);
            map.put("page",page);
        }else {
            Page<PaintingRecord> page = paintingRecordService.page(new Page(current, size), new QueryWrapper<PaintingRecord>()
                    .eq("wid", wid).orderByDesc("pid"));
            List<PaintingRecord> records = page.getRecords();
            for (PaintingRecord record : records) {
                record.setPid(null);
                record.setSid(null);
                record.setUserType(null);
                record.setUserHeadImg("");
                record.setUserNickname("");
                record.setUserUsername("");
                record.setParticulars(null);
                record.setGuidanceScale(null);
                record.setImgBi("");
                record.setNegativePrompts("");
                record.setSampler("");
                record.setSeed("");
                record.setSteps(null);
                record.setStyle("");
                record.setWid(null);
                record.setCarefullyImg(null);
                // 创建时间 文字描述 服务器类型 图片数据
            }
            page.setRecords(records);
            map.put("page",page);
        }
        map.put("userInfo",jsonObject);
        return OpenResult.success(map);
    }

    @GetMapping("/model/deduction/record/")
    public OpenResult modelRecord(HttpServletRequest request){
        JSONObject jsonObject = new JSONObject();
        String wid = jwtComponent.getUserWId(request);
        IpWhite ipWhite = ipWhiteService.lambdaQuery().eq(IpWhite::getWid, wid).eq(IpWhite::getIpStatus, 0).one();
        if (ipWhite == null) {
            return OpenResult.error("账户异常！");
        }
        jsonObject.set("username",ipWhite.getEmail());
        jsonObject.set("balance",ipWhite.getRequestCount());
        jsonObject.set("type",ipWhite.getUserType());
        jsonObject.set("resettingCount",ipWhite.getResettingCount()==null?0:ipWhite.getResettingCount());
        if (ipWhite.getUserType() == 0 || ipWhite.getUserType() == 1){
            jsonObject.set("resettingBalance",0);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 2){
            jsonObject.set("resettingBalance",35);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 3){
            jsonObject.set("resettingBalance",65);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }else if (ipWhite.getUserType() == 4){
            jsonObject.set("resettingBalance",95);
            jsonObject.set("limitationCount",ipWhite.getLimitationCount());
        }
        return OpenResult.success(jsonObject);
    }

    public boolean isReg(String socialUid){
        return ipWhiteService.lambdaQuery().eq(IpWhite::getSocialUid,socialUid)
                .count() == 0;
    }

    @GetMapping("/is/plus")
    public OpenResult isPlus(HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        IpWhite ipWhite = ipWhiteService.getById(wId);
        return OpenResult.success(ipWhite.getUserType());
    }

    @PostMapping("/user/share/chat")
    public OpenResult shareChat(@RequestBody JSONObject jsonObject,HttpServletRequest request){
        if (jsonObject.getLong("code") == null){
            return OpenResult.error("参数错误");
        }
        String wId = jwtComponent.getUserWId(request);
        IpWhite ipWhite = ipWhiteService.getById(wId);
        Map<String,String> map = new HashMap<>();
        map.put("code",String.valueOf(jsonObject.getLong("code")));
        map.put("time",String.valueOf(System.currentTimeMillis()));
        map.put("head_img",ipWhite.getHeadImg());
        map.put("is_plus_type",String.valueOf(ipWhite.getUserType()));
        return OpenResult.success(jwtComponent.generateToken(map));
    }

    @GetMapping("/user/get/share/chatting/{token}")
    public OpenResult shareChatting(@PathVariable String token){
        DecodedJWT decodedJWT;
        try {
            decodedJWT = jwtComponent.getTokenInfo(token);
        }catch (Exception e){
            return OpenResult.error("链接失效");
        }
        String code = decodedJWT.getClaim("code").asString();
        String headImg = decodedJWT.getClaim("head_img").asString();
        String userType = decodedJWT.getClaim("is_plus_type").asString();
        List<RequestRecord> requestRecordList = requestRecordService.lambdaQuery()
                .eq(RequestRecord::getGroupCode, code)
                .eq(RequestRecord::getIsDelete, 0)
                .list();
        Map<Long, List<RequestRecord>> longListMap = requestRecordList.stream().collect(Collectors.groupingBy(RequestRecord::getGroupCode));
        List<ChattingVo> chattingVoList = new ArrayList<>();
        List<String> dateList = new ArrayList<>();
        longListMap.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByKey())).forEachOrdered(x ->{
                String date = new SimpleDateFormat("yy年M月d日").format(x.getValue().get(0).getRequestTime());
                chattingVoList.add(new ChattingVo(x.getKey(), x.getValue(),!dateList.contains(date)?date:""));
                dateList.add(date);
            }
        );
        Map<String,Object> map = new HashMap<>();
        map.put("chattingList",chattingVoList);
        map.put("headImg",headImg);
        map.put("userType",userType);
        if (StrUtil.isBlank(requestRecordList.get(0).getModelType())){
            map.put("model","默认模型");
        }else {
            if (requestRecordList.get(0).getModelType().equals("gpt-3.5-turbo")) {
                map.put("model","默认模型");
            }else if (requestRecordList.get(0).getModelType().equals("gpt-3.5-turbo-0301")){
                map.put("model","新界模型");
            }else {
                map.put("model","识别模型");
            }
        }
        return OpenResult.success(map);
    }

    @GetMapping("/user/update/info/settings/{state}/{dialogueCount}/{temperature}")
    public OpenResult updateSettings(@PathVariable boolean state
            ,@PathVariable int dialogueCount,@PathVariable float temperature,HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        Integer sendMsgState = RedisUtil.get(wId+"sendMsg");
        if (sendMsgState == null){
            return updateSettings(state,dialogueCount,temperature,wId);
        }else {
            if (sendMsgState == 0){
                return updateSettings(state,dialogueCount,temperature,wId);
            } else {
                return OpenResult.error("请等待GPT消息返回完成后再来修改");
            }
        }
    }

    public OpenResult updateSettings(boolean state,int dialogueCount,float temperature,String wId){
        if (state){
            if (dialogueCount >= 1 && dialogueCount <= 10){
                boolean update = ipWhiteService.lambdaUpdate()
                        .set(IpWhite::getDialogueCount, dialogueCount)
                        .eq(IpWhite::getWid, wId).update();
                return OpenResult.update(update);
            }else {
                return OpenResult.error("请输入1~10之间的整数");
            }
        }else {
            if (temperature >= 0 && temperature <= 2){
                boolean update = ipWhiteService.lambdaUpdate()
                        .set(IpWhite::getTemperature, temperature)
                        .eq(IpWhite::getWid, wId).update();
                return OpenResult.update(update);
            }else {
                return OpenResult.error("请输入0~2之间的小数或整数");
            }
        }
    }

    @PostMapping("/user/distribution")
    public OpenResult distribution(HttpServletRequest request,@RequestBody JSONObject jsonObject){
        try {
            String wId = jwtComponent.getUserWId(request);
            IpWhite ipWhite = ipWhiteService.getById(wId);
            Integer count = ipWhiteService.lambdaQuery()
                    .eq(IpWhite::getEmail, jsonObject.getStr("username")).count();
            if (count != 0){
                return OpenResult.error("当前账号已经存在");
            }
            if (ipWhite.getUserType() < 2) {
                return OpenResult.error("必须是PLUS用户才可以使用分销");
            }
            if (jsonObject.getStr("username").trim().length() < 5){
                return OpenResult.error("账号至少大于5个字符");
            }
            if (jsonObject.getStr("password").trim().length() < 6){
                return OpenResult.error("密码长度不小于6位");
            }
            if (jsonObject.getInt("giveLimit") < 100){
                return OpenResult.error("赠送额度必须大于等于100");
            }
            if (ipWhite.getRequestCount() < jsonObject.getInt("giveLimit")){
                return OpenResult.error("请确认你自己的额度是否足够，请填写小于等于"+ipWhite.getRequestCount()+"的数值");
            }

            Integer dayCount = distributionRecordService.lambdaQuery()
                    .eq(DistributionRecord::getWid, wId)
                    .last("and DATE(create_time) = CURDATE()").count();

            if (dayCount >= 3){
                return OpenResult.error("每天最多分销3次");
            }

            saveUser(request,jsonObject.getStr("username"),jsonObject.getStr("password"),
                    jsonObject.getInt("giveLimit"),0,ipWhite.getLimitationCount() / 2,1,UserHead.getUserHeadImg());
            boolean update = ipWhiteService.lambdaUpdate()
                    .set(IpWhite::getRequestCount, ipWhite.getRequestCount() - jsonObject.getInt("giveLimit"))
                    .eq(IpWhite::getWid, wId).update();
            distributionRecordService.save(new DistributionRecord(null,Integer.parseInt(wId),
                    jsonObject.getStr("username").trim(),jsonObject.getStr("password").trim(),
                    jsonObject.getInt("giveLimit"),new Date()));
            return OpenResult.update(update);
        }catch (Exception e){
            e.printStackTrace();
            return OpenResult.error("分销账号出现了一个意外的错误");
        }
    }


    @GetMapping("/down/chat/records/{code}")
    public ResponseEntity<Resource> downChatRecords(@PathVariable String code, HttpServletRequest request, HttpServletResponse response){
        String wId = jwtComponent.getUserWId(request);
        List<RequestRecord> requestRecords = requestRecordService.lambdaQuery()
                .eq(RequestRecord::getGroupCode, code)
                .eq(RequestRecord::getWid, wId).list();
        if (requestRecords.size() != 0){
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/plain");
            String fileName = System.currentTimeMillis() + "_" + code;
            response.addHeader("Content-Disposition","attachment;filename="
                    + genAttachmentFileName( fileName, "JSON_FOR_UCC_")//设置名称格式，没有这个中文名称无法显示
                    + ".txt");
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
            String resultText = "";
            for (RequestRecord record : requestRecords) {
                if(StrUtil.isBlank(resultText)){
                    resultText = "官网平台地址：https://plumgpt.com/\n" +
                            "消息CODE码：10086\n" +
                            "消息条数：35条\n" +
                            "\n" +
                            "\n";
                }else {
                    String wen = "问："+record.getRequestContent() + "\n\n\n";
                    String da = "GPT:"+record.getRespondContent() + "\n\n\n";
                    resultText += wen + da;
                }
            }
            ByteArrayResource resource = new ByteArrayResource(resultText.getBytes());
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(resource.contentLength())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        }else {
            return null;
        }
    }

    @GetMapping("/update/head/sculpture/{number}")
    public OpenResult updateHeadSculpture(@PathVariable Integer number, HttpServletRequest request){
        String wId = jwtComponent.getUserWId(request);
        if (number >= 1 && number <= 51){
            String head = "https://plumgpt.com/chat/default/"+number+".jpg";
            boolean update = ipWhiteService.lambdaUpdate()
                    .set(IpWhite::getHeadIndex, number)
                    .set(IpWhite::getHeadImg, head)
                    .eq(IpWhite::getWid, wId).update();
            paintingRecordService.lambdaUpdate()
                    .set(PaintingRecord::getUserHeadImg, head)
                    .eq(PaintingRecord::getWid, wId)
                    .update();
            return OpenResult.update(update);
        }else {
            return OpenResult.error("头像索引错误");
        }
    }

    public  String genAttachmentFileName(String cnName, String defaultName) {
        try {
            cnName = new String(cnName.getBytes("gb2312"), "ISO8859-1");
        } catch (Exception e) {
            cnName = defaultName;
        }
        return cnName;
    }

}
